/*
 * To change this template, choose Tools | Templates
 * and open the template in the editor.
 */

package com.icee.myth.server.base.occupy;

import com.icee.myth.common.message.serverMessage.Message;
import com.icee.myth.common.messageQueue.ServerMessageQueue;
import com.icee.myth.config.MapConfig;
import com.icee.myth.protobuf.InternalCommonProtocol.DBOccupyInfoProto;
import com.icee.myth.server.GameServer;
import java.util.LinkedList;

/**
 *
 * @author liuxianke
 */
public class OccupyInfo {
    public final int id;        // 所属玩家id
    public String name;         // 所属玩家名
    public int level;           // 所属玩家等级
    public int rank;            // 所属玩家军衔
    public int leaderCardId;    // 队长卡片号
    public int leaderCardLevel; // 队长卡片等级
    public King king;           // 君主
    public LinkedList<CapeCollinson> capeCollinsons;    // 臣属
    public int production;      // 银矿产量
    public int silver;          // 银矿收获
    public long lastHarvestTime;    // 上次收获的时间
    public long lastCalculateTime;  // 上次计算收获的时间（0表示未计算）
    public long lastVisitTime;      // 上次访问此数据时间
    public boolean fighting;    // 战斗中标志
    public boolean inited;      // 数据初始化标志
    public boolean inMemory;    // 玩家数据是否在内存中
    public LinkedList<Message> waitingMessages;   // 等待数据初始化消息队列

    public long nextSaveToDBTime;   // 当数据发生改变时，记录需要写到数据库的时间

    public OccupyInfo(int id) {
        this.id = id;
    }

    public DBOccupyInfoProto buildDBOccupyInfoProto() {
        DBOccupyInfoProto.Builder builder = DBOccupyInfoProto.newBuilder();

        if (king != null) {
            builder.setKing(king.buildDBKingProto());
        }

        if (capeCollinsons != null) {
            for (CapeCollinson capeCollinson : capeCollinsons) {
                builder.addCapCollinsons(capeCollinson.buildDBCapeCollinsonProto());
            }
        }

        builder.setProduction(production);
        builder.setSilver(silver);
        builder.setLastHarvestTime(lastHarvestTime);
        builder.setLastCalculateTime(lastCalculateTime);

        return builder.build();
    }

    public void addWaitingMessage(Message message) {
        if (waitingMessages == null) {
            waitingMessages = new LinkedList<Message>();
        }

        waitingMessages.add(message);
    }

    public void waitUpWaitingMessage() {
        // 将等待的消息重新加入消息队列
        if (waitingMessages != null) {
            for (Message msg : waitingMessages) {
                ServerMessageQueue.queue().offer(msg);
            }

            waitingMessages = null;
        }
    }

    public CapeCollinson addCapeCollinson(int playerId, int production) {
        if (capeCollinsons == null) {
            capeCollinsons = new LinkedList<CapeCollinson>();
        }

        CapeCollinson capeCollinson = new CapeCollinson(playerId, production);
        capeCollinsons.add(capeCollinson);

        return capeCollinson;
    }

    public CapeCollinson getCapeCollinson(int playerId) {
        if (capeCollinsons != null) {
            for (CapeCollinson capeCollinson : capeCollinsons) {
                if (capeCollinson.id == playerId) {
                    return capeCollinson;
                }
            }
        }

        return null;
    }

    public void refreshSilver() {
        long currentTime = GameServer.INSTANCE.getCurrentTime();

        // 刷新自己的银矿收获（在有君主阶段所得减少10%）
        // times1:已计算收获的周期数
        int times1 = (lastCalculateTime > lastHarvestTime)?(int) ((lastCalculateTime - lastHarvestTime) / MapConfig.INSTANCE.minePeriod) : 0;
        // times2:到目前为止共可收获的周期数
        int times2 = (currentTime < lastHarvestTime + MapConfig.INSTANCE.mineFullTime)?(int) ((currentTime - lastHarvestTime) / MapConfig.INSTANCE.minePeriod):MapConfig.INSTANCE.mineFullTime/MapConfig.INSTANCE.minePeriod;
        if (times2 > times1) {
            if (king != null) {
                long setFreeTime = king.startTime + MapConfig.INSTANCE.maxOccupyTime;
                if (currentTime < setFreeTime) {
                    // 未获自由
                    silver += (int)(production * (1 - MapConfig.INSTANCE.mineTaxRatio)) * (times2 - times1);   // 扣税
                } else {
                    // 计算有君主期间的收获周期数
                    int times3 = (int) ((setFreeTime - lastHarvestTime) / MapConfig.INSTANCE.minePeriod);
                    if (times3 > times1) {
                        silver += (int)(production * (1 - MapConfig.INSTANCE.mineTaxRatio)) * (times3 - times1);   // 扣税
                        if (times2 > times3) {
                            silver += production * (times2 - times3);   // 不扣税
                        }
                    } else {
                        silver += production * (times2 - times1);
                    }

                    king = null;
                }
            } else {
                silver += production * (times2 - times1);
            }

            lastCalculateTime = currentTime;
            OccupyInfos.INSTANCE.setNeedSave(this);
        } else {
            if (king != null) {
                long setFreeTime = king.startTime + MapConfig.INSTANCE.maxOccupyTime;
                if (currentTime >= setFreeTime) {
                    king = null;
                }
            }
        }
    }

    public static void setFree(OccupyInfo capeOccupyInfo, OccupyInfo kingOccupyInfo) {
        // 脱离与原君主的臣属关系
        capeOccupyInfo.king = null;
        CapeCollinson capeCollinson = kingOccupyInfo.getCapeCollinson(capeOccupyInfo.id);
        capeCollinson.freeTime = GameServer.INSTANCE.getCurrentTime();
        OccupyInfos.INSTANCE.setNeedSave(capeOccupyInfo);
        OccupyInfos.INSTANCE.setNeedSave(kingOccupyInfo);
    }

    public static CapeCollinson occupy(OccupyInfo capeOccupyInfo, OccupyInfo kingOccupyInfo) {
        capeOccupyInfo.king = new King(kingOccupyInfo.id, capeOccupyInfo.production);
        CapeCollinson capeCollinson = kingOccupyInfo.addCapeCollinson(capeOccupyInfo.id, capeOccupyInfo.production);
        OccupyInfos.INSTANCE.setNeedSave(capeOccupyInfo);
        OccupyInfos.INSTANCE.setNeedSave(kingOccupyInfo);

        return capeCollinson;
    }

}
